package cn.hg.solon.youcan.system.provider;

import cn.hg.solon.youcan.common.exception.ServiceException;
import cn.hg.solon.youcan.easyquery.util.EntityQueryableUtil;
import cn.hg.solon.youcan.system.entity.DictItem;
import cn.hg.solon.youcan.system.entity.EqDictItem;
import cn.hg.solon.youcan.system.entity.proxy.EqDictItemProxy;
import cn.hg.solon.youcan.system.service.DictItemService;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.easy.query.api.proxy.entity.select.EntityQueryable;
import com.easy.query.core.api.pagination.EasyPageResult;
import com.easy.query.solon.annotation.Db;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.bean.copier.CopyOptions;
import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.text.StrValidator;
import org.dromara.hutool.core.util.ObjUtil;
import org.dromara.hutool.db.Page;
import org.dromara.hutool.db.PageResult;
import org.noear.solon.annotation.Component;
import org.noear.solon.data.annotation.Tran;

import java.util.List;
import java.util.Map;

/**
 * @author 胡高
 */
@Component
public class EqDictItemProvider implements DictItemService {

    @Db("db1")
    private EasyEntityQuery easyEntityQuery;


    private EntityQueryable<EqDictItemProxy, EqDictItem> buildQuery(Page page, Map<String, Object> paraMap) {
        String type = (String) paraMap.get("type");
        String word = (String) paraMap.get("word");

        EntityQueryable<EqDictItemProxy, EqDictItem> entityQueryable = this.easyEntityQuery
                // FROM sys_dict_item AS t
                .queryable(EqDictItem.class)
                // WHERE t.`type` = ${type} AND (t.`label` LIKE '%${word}%' OR t.`value` LIKE '%${word}%'
                //      OR t.`css_class` LIKE '%${word}%' OR t.`list_class` LIKE '%${word}%')
                .where(t -> {
                            t.type().eq(StrValidator.isNotBlank(type), type);
                            t.or(StrValidator.isNotBlank(word), () -> {
                                t.label().like(word);
                                t.value().like(word);
                                t.cssClass().like(word);
                                t.listClass().like(word);
                            });
                        }
                );
        // ORDER BY t.${sortField}
        return EntityQueryableUtil.applyOrderBy(entityQueryable, page);
    }


    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#checkUnique(cn.hg.solon.youcan.system.entity.DictItem)
     */
    @Override
    public boolean checkUnique(DictItem bean) {
        return !this.easyEntityQuery
                // FROM sys_dict_item AS t
                .queryable(EqDictItem.class)
                // WHERE t.`type` = ${bean.type}
                .where(t -> {
                    t.type().eq(bean.getType());
                    // AND t.`value` = ${bean.value}
                    t.value().eq(bean.getValue());
                    // AND t.`id` <> ${bean.id}
                    t.id().ne(ObjUtil.isNotNull(bean.getId()), bean.getId());
                })
                .any();
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#delete(java.util.List)
     */
    @Tran
    @Override
    public boolean delete(List<Integer> idList) {
        return this.easyEntityQuery.deletable(EqDictItem.class).where(t -> t.id().in(idList)).executeRows() > 0L;
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#get(java.lang.Integer)
     */
    @Override
    public EqDictItem get(Integer id) {
        return this.easyEntityQuery.queryable(EqDictItem.class).whereById(id).firstOrNull();
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#getByTypeAndValue(java.lang.String, java.lang.String)
     */
    @Override
    public EqDictItem getByTypeAndValue(String type, String value) {
        return this.easyEntityQuery
                // FROM sys_dict_item AS t
                .queryable(EqDictItem.class)
                // WHERE t.`type` = ${type} AND t.`value` = ${value}
                .where(t -> {
                    t.type().eq(type);
                    t.value().eq(value);
                })
                .firstOrNull();
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#insert(cn.hg.solon.youcan.system.entity.DictItem)
     */
    @Tran
    @Override
    public boolean insert(DictItem bean) {
        if (!this.checkUnique(bean)) {
            throw new ServiceException("字典键值已经存在，请更换其它值！");
        }

        EqDictItem cloneBean = BeanUtil.copyProperties(bean, EqDictItem.class);

        return this.easyEntityQuery.insertable(cloneBean).executeRows() > 0L;
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#listByType(java.lang.String, java.lang.String)
     */
    @Override
    public List<EqDictItem> listByType(String type, String status) {
        return this.easyEntityQuery
                // FROM sys_dict_item AS t
                .queryable(EqDictItem.class)
                // WHERE t.`type` = ${type} AND t.`status` = ${status}
                .where(t -> {
                    t.type().eq(type);
                    t.status().eq(status);
                })
                .toList();
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#pageBy(int, int, java.util.Map)
     */
    @Override
    public PageResult<EqDictItem> pageBy(Page page, Map<String, Object> paraMap) {
        EasyPageResult<EqDictItem> pageList = this.buildQuery(page, paraMap).toPageResult(page.getPageNumber(), page.getPageSize());

        PageResult<EqDictItem> result = new PageResult<>();
        result.addAll(pageList.getData());
        result.setTotal(ConvertUtil.toInt(pageList.getTotal()));

        return result;
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#update(cn.hg.solon.youcan.system.entity.DictItem)
     */
    @Tran
    @Override
    public boolean update(DictItem bean) {
        if (!this.checkUnique(bean)) {
            throw new ServiceException("字典键值已经存在，请更换其它值！");
        }

        EqDictItem cloneBean = this.get(bean.getId());

        BeanUtil.copyProperties(bean, cloneBean, CopyOptions.of().setIgnoreNullValue(true));

        return this.easyEntityQuery.updatable(cloneBean).executeRows() > 0L;
    }

    /* (non-Javadoc)
     * @see cn.hg.solon.youcan.system.service.DictItemService#updateTypeName(java.lang.String, java.lang.String)
     */
    @Tran
    @Override
    public boolean updateTypeName(String oldType, String newType) {
        return this.easyEntityQuery
                // UPDATE sys_dict_item AS t
                .updatable(EqDictItem.class)
                // SET t.`type` = ${newType}
                .setColumns(t -> t.type().set(newType))
                // WHERE t.`type` = ${oldType}
                .where(t -> t.type().eq(oldType))
                .executeRows() > 0L;
    }

}
